| | |
| | | package com.stylefeng.guns.modular.system.service.impl; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.baomidou.mybatisplus.service.impl.ServiceImpl; |
| | | import com.stylefeng.guns.core.util.ToolUtil; |
| | | import com.stylefeng.guns.modular.smallLogistics.model.OrderLogistics; |
| | | import com.stylefeng.guns.modular.smallLogistics.server.IOrderLogisticsService; |
| | | import com.stylefeng.guns.modular.specialTrain.model.OrderPrivateCar; |
| | | import com.stylefeng.guns.modular.specialTrain.server.IOrderPrivateCarService; |
| | | import com.stylefeng.guns.modular.system.dao.DriverActivityHistoryMapper; |
| | | import com.stylefeng.guns.modular.system.dao.DriverActivityOnlineMapper; |
| | | import com.stylefeng.guns.modular.system.dao.DriverOnlineMapper; |
| | | import com.stylefeng.guns.modular.system.model.Driver; |
| | | import com.stylefeng.guns.modular.system.model.DriverAssessment; |
| | | import com.stylefeng.guns.modular.system.model.DriverOnline; |
| | | import com.stylefeng.guns.modular.system.model.DriverWork; |
| | | import com.stylefeng.guns.modular.system.model.*; |
| | | import com.stylefeng.guns.modular.system.service.IDriverAssessmentService; |
| | | import com.stylefeng.guns.modular.system.service.IDriverOnlineService; |
| | | import com.stylefeng.guns.modular.system.service.IDriverService; |
| | | import com.stylefeng.guns.modular.system.service.IDriverWorkService; |
| | | import com.stylefeng.guns.modular.system.util.PushUtil; |
| | | import com.stylefeng.guns.modular.system.util.RedisUtil; |
| | | import com.stylefeng.guns.modular.system.util.TextToSpeechUtil; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.io.BufferedReader; |
| | | import java.io.IOException; |
| | | import java.io.InputStreamReader; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Service |
| | | public class DriverOnlineServiceImpl extends ServiceImpl<DriverOnlineMapper, DriverOnline> implements IDriverOnlineService { |
| | |
| | | |
| | | @Autowired |
| | | private IDriverService driverService; |
| | | |
| | | @Resource |
| | | private DriverActivityOnlineMapper driverActivityOnlineMapper; |
| | | |
| | | @Resource |
| | | private DriverActivityHistoryMapper driverActivityHistoryMapper; |
| | | |
| | | @Autowired |
| | | private IOrderPrivateCarService orderPrivateCarService; |
| | | |
| | | @Autowired |
| | | private IOrderLogisticsService orderLogisticsService; |
| | | |
| | | @Autowired |
| | | private PushUtil pushUtil; |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | |
| | | public void addDriverOnline(Integer driverId) throws Exception { |
| | | DriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", driverId).eq("state", 1)); |
| | | if(null == driverWork){//非上班状态不记录 |
| | | redisUtil.remove("ONLINE_" + driverId); |
| | | for (int i = 1; i < 5; i++) { |
| | | redisUtil.remove("ONLINE_" + i + "_" + driverId); |
| | | } |
| | | return; |
| | | } |
| | | |
| | | //查询数据及条件判断 |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
| | | DriverOnline query = driverOnlineMapper.query(driverId, sdf.format(new Date()), 0);//正常记录数据 |
| | | DriverOnline query1 = null;//考勤范围内的数据 |
| | | DriverAssessment driverAssessment = driverAssessmentService.selectOne(new EntityWrapper<DriverAssessment>() |
| | | .eq("companyId", driverService.selectById(driverId).getCompanyId())); |
| | | Date s = null; |
| | | Date e = null; |
| | | long now = System.currentTimeMillis(); |
| | | if(null != driverAssessment){//在考勤范围内记录数据 |
| | | SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | String[] split = driverAssessment.getAssessment().split(" - "); |
| | | s = sdf1.parse(sdf.format(new Date()) + " " + split[0]); |
| | | e = sdf1.parse(sdf.format(new Date()) + " " + split[1]); |
| | | if(now > s.getTime() && now <= e.getTime()){ |
| | | query1 = driverOnlineMapper.query(driverId, sdf.format(new Date()), 1); |
| | | } |
| | | } |
| | | |
| | | //开始修改数据 |
| | | if(query != null){ |
| | | String value = redisUtil.getValue("ONLINE_" + driverId); |
| | | if(ToolUtil.isEmpty(value)){ |
| | | redisUtil.setStrValue("ONLINE_" + driverId, String.valueOf(now / 1000));//存入秒 |
| | | return; |
| | | } |
| | | Long ss = (now / 1000) - Long.valueOf(value); |
| | | if(ss.longValue() >= 600){//间隔时间大于10分钟则为离线 |
| | | redisUtil.remove("ONLINE_" + driverId); |
| | | return; |
| | | } |
| | | |
| | | query.setDuration(query.getDuration() + ss); |
| | | driverOnlineMapper.updateById(query); |
| | | |
| | | //记录考勤范围内的数据 |
| | | if(null != s && null != e && now > s.getTime() && now <= e.getTime()){ |
| | | if(null != query1){ |
| | | query1.setDuration(query1.getDuration() + ss); |
| | | driverOnlineMapper.updateById(query1); |
| | | }else{ |
| | | query1 = new DriverOnline(); |
| | | query1.setDriverId(driverId); |
| | | query1.setDate(new Date()); |
| | | query1.setAssessment(1); |
| | | query1.setDuration(ss); |
| | | driverOnlineMapper.insert(query1); |
| | | String[] split1 = driverWork.getType().split(","); |
| | | for (String ty : split1) { |
| | | //查询数据及条件判断 |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
| | | DriverOnline query = driverOnlineMapper.query(driverId, sdf.format(new Date()), Integer.valueOf(ty), 0);//正常记录数据 |
| | | DriverOnline query1 = null;//考勤范围内的数据 |
| | | DriverAssessment driverAssessment = driverAssessmentService.selectOne(new EntityWrapper<DriverAssessment>() |
| | | .eq("companyId", driverService.selectById(driverId).getCompanyId())); |
| | | Date s = null; |
| | | Date e = null; |
| | | long now = System.currentTimeMillis(); |
| | | if(null != driverAssessment){//在考勤范围内记录数据 |
| | | SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | String[] split = driverAssessment.getAssessment().split(" - "); |
| | | s = sdf1.parse(sdf.format(new Date()) + " " + split[0]); |
| | | e = sdf1.parse(sdf.format(new Date()) + " " + split[1]); |
| | | if(now > s.getTime() && now <= e.getTime()){ |
| | | query1 = driverOnlineMapper.query(driverId, sdf.format(new Date()), Integer.valueOf(ty), 1); |
| | | } |
| | | } |
| | | |
| | | }else{ |
| | | DriverOnline driverOnline = new DriverOnline(); |
| | | driverOnline.setDriverId(driverId); |
| | | driverOnline.setDate(new Date()); |
| | | driverOnline.setAssessment(0); |
| | | driverOnline.setDuration(0L); |
| | | driverOnlineMapper.insert(driverOnline); |
| | | |
| | | //开始修改数据 |
| | | if(query != null){ |
| | | String value = redisUtil.getValue("ONLINE_" + ty + "_" + driverId); |
| | | if(ToolUtil.isEmpty(value)){ |
| | | redisUtil.setStrValue("ONLINE_" + ty + "_" + driverId, String.valueOf(now / 1000));//存入秒 |
| | | return; |
| | | } |
| | | Long ss = (now / 1000) - Long.valueOf(value); |
| | | if(ss.longValue() >= 600){//间隔时间大于10分钟则为离线 |
| | | redisUtil.remove("ONLINE_" + ty + "_" + driverId); |
| | | return; |
| | | } |
| | | |
| | | query.setDuration(query.getDuration() + ss); |
| | | driverOnlineMapper.updateById(query); |
| | | |
| | | //记录考勤范围内的数据 |
| | | if(null != s && null != e && now > s.getTime() && now <= e.getTime()){ |
| | | if(null != query1){ |
| | | query1.setDuration(query1.getDuration() + ss); |
| | | driverOnlineMapper.updateById(query1); |
| | | }else{ |
| | | query1 = new DriverOnline(); |
| | | query1.setDriverId(driverId); |
| | | query1.setType(Integer.valueOf(ty)); |
| | | query1.setDate(new Date()); |
| | | query1.setAssessment(1); |
| | | query1.setDuration(ss); |
| | | driverOnlineMapper.insert(query1); |
| | | } |
| | | } |
| | | }else{ |
| | | DriverOnline driverOnline = new DriverOnline(); |
| | | driverOnline.setDriverId(driverId); |
| | | driverOnline.setType(Integer.valueOf(ty)); |
| | | driverOnline.setDate(new Date()); |
| | | driverOnline.setAssessment(0); |
| | | driverOnline.setDuration(0L); |
| | | driverOnlineMapper.insert(driverOnline); |
| | | } |
| | | redisUtil.setStrValue("ONLINE_" + ty + "_" + driverId, String.valueOf(now / 1000));//存入秒 |
| | | } |
| | | redisUtil.setStrValue("ONLINE_" + driverId, String.valueOf(now / 1000));//存入秒 |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | @Override |
| | | public void addDriverOnline1(Integer driverId) throws Exception { |
| | | DriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", driverId).eq("state", 1)); |
| | | if(null == driverWork){//非上班状态不记录 |
| | | return; |
| | | } |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
| | | List<DriverActivityHistory> driverActivityHistories = driverActivityHistoryMapper.selectList(new EntityWrapper<DriverActivityHistory>().eq("driverId", driverId) |
| | | .eq("type", 3).eq("carryOut", 1).last(" and day = '" + sdf.format(new Date()) + "' and driverActivityId in (select id from t_driver_activity where status = 3 and now() between startTime and endTime)")); |
| | | //生成每个活动从开始上班到当前时间的时长记录 |
| | | for (DriverActivityHistory driverActivityHistory : driverActivityHistories) { |
| | | String value = redisUtil.getValue("driverActivity_" + driverId + "_" + driverActivityHistory.getId()); |
| | | if(ToolUtil.isNotEmpty(value)){ |
| | | JSONObject jsonObject = JSON.parseObject(value); |
| | | Long startTime = jsonObject.getLong("startTime"); |
| | | long time = System.currentTimeMillis() - startTime; |
| | | redisUtil.setStrValue("driverActivity_" + driverId + "_" + driverActivityHistory.getId(), "{\"startTime\":" + startTime + ", \"time\":" + time + "}", 172800); |
| | | }else{ |
| | | long time = System.currentTimeMillis() - driverWork.getStartTime().getTime(); |
| | | redisUtil.setStrValue("driverActivity_" + driverId + "_" + driverActivityHistory.getId(), "{\"startTime\":" + driverWork.getStartTime().getTime() + ", \"time\":" + time + "}", 172800); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取给定日期范围的在线时长 |
| | | * @param driverId |
| | |
| | | public Integer querySumTime(Integer driverId, Integer assessment, Date start, Date end) { |
| | | return driverOnlineMapper.querySumTime(driverId, assessment, start, end); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 定时检测司机是否连续接单 |
| | | */ |
| | | @Override |
| | | public void deductionDuration() { |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
| | | String format = sdf.format(new Date()); |
| | | List<DriverActivityHistory> driverActivityHistories = driverActivityHistoryMapper.selectList(new EntityWrapper<DriverActivityHistory>().eq("DATE_FORMAT(day, '%Y-%m-%d')", format).eq("type", 3).eq("carryOut", 1)); |
| | | List<Integer> collect = driverActivityHistories.stream().map(DriverActivityHistory::getDriverId).collect(Collectors.toList()); |
| | | if(collect.size() == 0){ |
| | | return; |
| | | } |
| | | for (DriverActivityHistory driverActivityHistory : driverActivityHistories) { |
| | | DriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", driverActivityHistory.getDriverId()).eq("state", 1)); |
| | | if(null == driverWork){ |
| | | continue; |
| | | } |
| | | DriverActivityOnline driverActivityOnline = driverActivityOnlineMapper.selectById(driverActivityHistory.getActivityId()); |
| | | DriverOnline driverOnline = this.selectOne(new EntityWrapper<DriverOnline>().eq("DATE_FORMAT(date, '%Y-%m-%d')", format) |
| | | .eq("driverId", driverActivityHistory.getDriverId()).eq("type", driverActivityOnline.getType())); |
| | | if(null == driverOnline){ |
| | | continue; |
| | | } |
| | | Integer driverId = driverOnline.getDriverId(); |
| | | Driver driver1 = driverService.selectById(driverId); |
| | | long m = Double.valueOf(driverActivityOnline.getOfflineTime() * 3600000L).longValue(); |
| | | |
| | | //找出最后一次接单的时间 |
| | | long mm = 0L; |
| | | OrderPrivateCar orderPrivateCar = orderPrivateCarService.selectOne(new EntityWrapper<OrderPrivateCar>().eq("driverId", driverId).eq("isDelete", 1).ne("state", 10)); |
| | | Date snatchOrderTime = null; |
| | | if(null != orderPrivateCar){ |
| | | snatchOrderTime = orderPrivateCar.getSnatchOrderTime(); |
| | | mm = snatchOrderTime.getTime(); |
| | | } |
| | | OrderLogistics orderLogistics = orderLogisticsService.selectOne(new EntityWrapper<OrderLogistics>().eq("driverId", driverId).eq("isDelete", 1).ne("state", 10)); |
| | | if(null != orderLogistics && (null == snatchOrderTime || snatchOrderTime.before(orderLogistics.getSnatchOrderTime()))){ |
| | | mm = orderLogistics.getSnatchOrderTime().getTime(); |
| | | } |
| | | |
| | | //超时不接单,直接将之前的在线时长清零 |
| | | //推送司机下班提醒 |
| | | if((System.currentTimeMillis() - mm) >= m){ |
| | | this.deleteById(driverOnline.getId()); |
| | | driverWork.setState(2); |
| | | driverWork.setEndTime(new Date()); |
| | | driverWorkService.updateById(driverWork); |
| | | Driver driver = driverService.selectById(driverWork.getDriverId()); |
| | | driver.setState(1); |
| | | driverService.updateById(driver); |
| | | Integer language = driver.getLanguage(); |
| | | |
| | | String msg = language == 1 ? "您已连续" + driverActivityOnline.getOfflineTime() + "小时未接单,系统将强制更改您的状态为:下班" : |
| | | language == 2 ? "You have not been accepting orders for " + driverActivityOnline.getOfflineTime() + " hour(s) System will change your state to Off-work" : |
| | | "Vous n’acceptez pas de commandes depuis " + driverActivityOnline.getOfflineTime() + " heure(s) Le système changera votre état en Hors travail"; |
| | | String fileName = "OffLine" + driver.getId() + ".mp3"; |
| | | String audioUrl = null; |
| | | try { |
| | | audioUrl = TextToSpeechUtil.create(language == 1 ? "cmn-CN" : language == 2 ? "en-US" : "fr-FR", msg, fileName); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | Map<String, String> map = new HashMap<>(); |
| | | map.put("msg", msg); |
| | | map.put("audioUrl", audioUrl); |
| | | pushUtil.afterWork(driverOnline.getDriverId(), 2, map); |
| | | |
| | | //定时任务删除语音文件 |
| | | new Timer().schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | try { |
| | | // 使用Runtime执行命令 |
| | | Process process = Runtime.getRuntime().exec("sudo rm -rf /home/igotechgh/nginx/html/files/audio/" + fileName); |
| | | // 读取命令的输出 |
| | | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); |
| | | String line; |
| | | while ((line = reader.readLine()) != null) { |
| | | System.out.println(line); |
| | | } |
| | | // 等待命令执行完成 |
| | | process.waitFor(); |
| | | // 关闭流 |
| | | reader.close(); |
| | | } catch (IOException | InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | }, 30000); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void deductionDuration1() { |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
| | | List<DriverActivityHistory> driverActivityHistories = driverActivityHistoryMapper.selectList(new EntityWrapper<DriverActivityHistory>() |
| | | .eq("type", 3).eq("carryOut", 1).last(" and day = '" + sdf.format(new Date()) + "' and driverActivityId in (select id from t_driver_activity where status = 3 and now() between startTime and endTime)")); |
| | | for (DriverActivityHistory driverActivityHistory : driverActivityHistories) { |
| | | DriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", driverActivityHistory.getDriverId()).eq("state", 1)); |
| | | if(null == driverWork){ |
| | | continue; |
| | | } |
| | | DriverActivityOnline driverActivityOnline = driverActivityOnlineMapper.selectById(driverActivityHistory.getActivityId()); |
| | | //在线连续xx小时不接单,司机下线,时长不计入总累计时长 |
| | | int m = Double.valueOf(driverActivityOnline.getOfflineTime() * 60).intValue(); |
| | | String value = redisUtil.getValue("driverActivity_" + driverActivityHistory.getDriverId() + "_" + driverActivityHistory.getId()); |
| | | if(ToolUtil.isEmpty(value)){ |
| | | continue; |
| | | } |
| | | JSONObject jsonObject = JSON.parseObject(value); |
| | | //开始记录时长的时间开始时间戳 |
| | | Long startTime = jsonObject.getLong("startTime"); |
| | | //在线时长累计 |
| | | Long time = jsonObject.getLong("time") / 60000; |
| | | int count1 = orderPrivateCarService.selectCount(new EntityWrapper<OrderPrivateCar>().eq("driverId", driverActivityHistory.getDriverId()) |
| | | .eq("isDelete", 1).ne("state", 10).last(" and UNIX_TIMESTAMP(snatchOrderTime) > " + (startTime) / 1000)); |
| | | int count2 = orderLogisticsService.selectCount(new EntityWrapper<OrderLogistics>().eq("driverId", driverActivityHistory.getDriverId()) |
| | | .eq("isDelete", 1).ne("state", 10).last(" and UNIX_TIMESTAMP(snatchOrderTime) > " + (startTime) / 1000)); |
| | | |
| | | Driver driver = driverService.selectById(driverWork.getDriverId()); |
| | | //阶段时间累计时长超过设定时长且没有接单,不计入累计总时长(司机服务中不下班) |
| | | if(m <= time && count1 + count2 == 0 && driver.getState() != 3){ |
| | | //司机下班,清空当前阶段的累计时长 |
| | | driverWork.setState(2); |
| | | driverWork.setEndTime(new Date()); |
| | | driverWorkService.updateById(driverWork); |
| | | driver.setState(1); |
| | | driverService.updateById(driver); |
| | | redisUtil.remove("driverActivity_" + driverActivityHistory.getDriverId() + "_" + driverActivityHistory.getId()); |
| | | Integer language = driver.getLanguage(); |
| | | |
| | | String msg = language == 1 ? "您已连续" + driverActivityOnline.getOfflineTime() + "小时未接单,系统将强制更改您的状态为:下班" : |
| | | language == 2 ? "You have not been accepting orders for " + driverActivityOnline.getOfflineTime() + " hour(s) System will change your state to Off-work" : |
| | | "Vous n’acceptez pas de commandes depuis " + driverActivityOnline.getOfflineTime() + " heure(s) Le système changera votre état en Hors travail"; |
| | | String fileName = "OffLine" + driver.getId() + ".mp3"; |
| | | String audioUrl = null; |
| | | try { |
| | | audioUrl = TextToSpeechUtil.create(language == 1 ? "cmn-CN" : language == 2 ? "en-US" : "fr-FR", msg, fileName); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | Map<String, String> map = new HashMap<>(); |
| | | map.put("msg", msg); |
| | | map.put("audioUrl", audioUrl); |
| | | pushUtil.afterWork(driverWork.getDriverId(), 2, map); |
| | | |
| | | //定时任务删除语音文件 |
| | | new Timer().schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | try { |
| | | // 使用Runtime执行命令 |
| | | Process process = Runtime.getRuntime().exec("sudo rm -rf /home/igotechgh/nginx/html/files/audio/" + fileName); |
| | | // 读取命令的输出 |
| | | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); |
| | | String line; |
| | | while ((line = reader.readLine()) != null) { |
| | | System.out.println(line); |
| | | } |
| | | // 等待命令执行完成 |
| | | process.waitFor(); |
| | | // 关闭流 |
| | | reader.close(); |
| | | } catch (IOException | InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | }, 30000); |
| | | } |
| | | //阶段时间累计有新的订单,计入累计总时长,重置新的开始统计时间戳 |
| | | if(m <= time && count1 + count2 > 0){ |
| | | DriverOnline driverOnline = this.selectOne(new EntityWrapper<DriverOnline>().eq("DATE_FORMAT(date, '%Y-%m-%d')", sdf.format(new Date())) |
| | | .eq("driverId", driverActivityHistory.getDriverId())); |
| | | if(null == driverOnline){ |
| | | driverOnline = new DriverOnline(); |
| | | driverOnline.setDriverId(driverActivityHistory.getDriverId()); |
| | | driverOnline.setDate(new Date()); |
| | | driverOnline.setDuration(time * 60); |
| | | driverOnline.setInsertTime(new Date()); |
| | | this.insert(driverOnline); |
| | | }else{ |
| | | driverOnline.setDuration(driverOnline.getDuration() + (time * 60)); |
| | | this.updateById(driverOnline); |
| | | } |
| | | redisUtil.setStrValue("driverActivity_" + driverActivityHistory.getDriverId() + "_" + driverActivityHistory.getId(), "{\"startTime\":" + System.currentTimeMillis() + ", \"time\":" + 0 + "}", 172800); |
| | | } |
| | | } |
| | | } |
| | | } |