Pu Zhibing
7 天以前 4c99ee7028c3fe58a2cd4b8273b22c75c45574fc
DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DriverOnlineServiceImpl.java
@@ -1,24 +1,35 @@
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 {
@@ -37,6 +48,24 @@
    @Autowired
    private IDriverService driverService;
    @Resource
    private DriverActivityOnlineMapper driverActivityOnlineMapper;
    @Resource
    private DriverActivityHistoryMapper driverActivityHistoryMapper;
    @Autowired
    private IOrderPrivateCarService orderPrivateCarService;
    @Autowired
    private IOrderLogisticsService orderLogisticsService;
    @Autowired
    private PushUtil pushUtil;
    /**
@@ -48,72 +77,101 @@
    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
@@ -126,4 +184,199 @@
    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);
            }
        }
    }
}