zhibing.pu
2024-09-02 bf2ce859f26ab06c4c0502043b67ea58284c3588
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
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.*;
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.*;
import java.util.stream.Collectors;
 
@Service
public class DriverOnlineServiceImpl extends ServiceImpl<DriverOnlineMapper, DriverOnline> implements IDriverOnlineService {
 
    @Resource
    private DriverOnlineMapper driverOnlineMapper;
 
    @Autowired
    private RedisUtil redisUtil;
 
    @Autowired
    private IDriverWorkService driverWorkService;
 
    @Autowired
    private IDriverAssessmentService driverAssessmentService;
 
    @Autowired
    private IDriverService driverService;
    
    @Resource
    private DriverActivityOnlineMapper driverActivityOnlineMapper;
    
    @Resource
    private DriverActivityHistoryMapper driverActivityHistoryMapper;
    
    @Autowired
    private IOrderPrivateCarService orderPrivateCarService;
    
    @Autowired
    private IOrderLogisticsService orderLogisticsService;
    
    @Autowired
    private PushUtil pushUtil;
    
    
    
 
 
    /**
     * 添加数据
     * @param driverId
     * @throws Exception
     */
    @Override
    public void addDriverOnline(Integer driverId) throws Exception {
        DriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", driverId).eq("state", 1));
        if(null == driverWork){//非上班状态不记录
            for (int i = 1; i < 5; i++) {
                redisUtil.remove("ONLINE_" + i + "_" + driverId);
            }
            return;
        }
        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);
                }
            }
    
            //开始修改数据
            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));//存入秒
        }
    }
    
    
    @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
     * @param assessment
     * @param start yyyy-MM-dd
     * @param end   yyyy-MM-dd
     * @return
     */
    @Override
    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() {
                        Process process = null;
                        try {
                            process = Runtime.getRuntime().exec("sudo rm -rf /home/igotechgh/nginx/html/files/audio/" + fileName);
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                        if (process != null) {
                            process.destroy();
                        }
                    }
                }, 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() {
                        Process process = null;
                        try {
                            process = Runtime.getRuntime().exec("sudo rm -rf /home/igotechgh/nginx/html/files/audio/" + fileName);
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                        if (process != null) {
                            process.destroy();
                        }
                    }
                }, 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);
            }
        }
    }
}