Pu Zhibing
2025-04-25 b35b859957e3f8aac2f7d70b7a13f5eb16056840
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
package com.stylefeng.guns.modular.system.util.quartz.jobs;
 
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.controller.util.PushUtil;
import com.stylefeng.guns.modular.system.dao.TUserMapper;
import com.stylefeng.guns.modular.system.model.TDriver;
import com.stylefeng.guns.modular.system.model.TOrderLogistics;
import com.stylefeng.guns.modular.system.model.TOrderPrivateCar;
import com.stylefeng.guns.modular.system.model.TUser;
import com.stylefeng.guns.modular.system.service.ITDriverService;
import com.stylefeng.guns.modular.system.service.ITOrderLogisticsService;
import com.stylefeng.guns.modular.system.service.ITOrderPrivateCarService;
import com.stylefeng.guns.modular.system.util.HttpRequestUtil;
import com.stylefeng.guns.modular.system.util.PushURL;
import com.stylefeng.guns.modular.system.util.TextToSpeechUtil;
import com.stylefeng.guns.modular.system.util.quartz.QuartzUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
 
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.*;
 
 
/**
 * 订单司机超时提醒任务
 * @author zhibing.pu
 * @Date 2024/4/18 15:19
 */
@Slf4j
@Component
public class OrderTimeOutJob implements Job {
    
    @Resource
    private PushUtil pushUtil;
    @Resource
    private ITOrderPrivateCarService orderPrivateCarService;
    @Resource
    private ITOrderLogisticsService orderLogisticsService;
    @Resource
    private ITDriverService driverService;
    @Resource
    private TUserMapper userInfoMapper;
    
    @Resource
    private QuartzUtil quartzUtil;
 
    
    /**
     * 执行的业务逻辑
     * @param jobExecutionContext 定时任务上下文对象
     */
    public void run(JobExecutionContext jobExecutionContext) {
        JobDetail jobDetail = jobExecutionContext.getJobDetail();
        JobDataMap jobDataMap = jobDetail.getJobDataMap();
        String name = jobDetail.getKey().getName();
        log.info("执行{}定时任务逻辑 JobDataMap:{}", name, JSON.toJSONString(jobDataMap));
        Integer timeOutType = jobDataMap.getIntValue("timeOutType");
        Integer driverId = jobDataMap.getIntValue("driverId");
        Integer orderId = jobDataMap.getIntValue("orderId");
        Integer orderType = jobDataMap.getIntValue("orderType");
        Integer driverTimeout = jobDataMap.getIntValue("driverTimeout");
        long timeOut = jobDataMap.getLongValue("timeOut");
        String describe = jobDataMap.getString("describe");
        TDriver driver = driverService.selectById(driverId);
        Integer language = driver.getLanguage();
        if(1 == timeOutType){
            if(orderType == 1){
                describe = language == 1 ? "您已超时" + driverTimeout + "分钟,\n用户可免费取消订单" : language == 2 ? "You are overdue for " + driverTimeout + " minutes,\nThe subscriber could cancel the order for free" : "Vous êtes en retard de " + driverTimeout + " minutes,\nL'abonné peut annuler la commande gratuitement";
            }
            if(orderType == 4){
                describe = language == 1 ? "您已超时" + driverTimeout + "分钟,\n用户可免费取消订单" : language == 2 ? "You are overdue for " + driverTimeout + " minutes,\nThe subscriber could cancel the order for free" : "Vous êtes en retard de " + driverTimeout + " minutes,\nL'abonné peut annuler la commande gratuitement";
            }
        }
        if(2 == timeOutType){
            if(orderType == 1){
                TOrderPrivateCar orderPrivateCar = orderPrivateCarService.selectById(orderId);
                TUser userInfo = userInfoMapper.selectById(orderPrivateCar.getUserId());
                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
                describe = language == 1 ? "您将于" + sdf.format(orderPrivateCar.getTravelTime()) + "去接" + (ToolUtil.isEmpty(userInfo.getFirstName()) ? userInfo.getNickName() : userInfo.getFirstName() + " " + userInfo.getLastName())  + ",请准时!" :
                        language == 2 ? "You are going to pick up " + (ToolUtil.isEmpty(userInfo.getFirstName()) ? userInfo.getNickName() : userInfo.getFirstName() + " " + userInfo.getLastName()) + " at " + sdf.format(orderPrivateCar.getTravelTime()) + ", please be on time. " :
                                "Vous allez chercher " + (ToolUtil.isEmpty(userInfo.getFirstName()) ? userInfo.getNickName() : userInfo.getFirstName() + " " + userInfo.getLastName()) + " à " + sdf.format(orderPrivateCar.getTravelTime()) + ", s’il vous plaît soyez à l’heure.";
            }
            if(orderType == 4){
            }
        }
        if(3 == timeOutType){
            Integer m = Double.valueOf((System.currentTimeMillis() - timeOut) / 60000).intValue();
            if(orderType == 1){
                if(0 == m){
                    describe = language == 1 ? "您的打车订单已超时,请抓紧!" : language == 2 ? "Your ride order is overdue, please go faster." : "Votre commande de course est en retard, veuillez aller plus vite.";
                }else{
                    describe = language == 1 ? "您的打车订单已超时" + m + "分钟,请抓紧!" : language == 2 ? "Your ride order is overdue for " + m + " minute(s), please go faster." : "Votre commande de course est en retard depuis " + m + " minute(s), veuillez aller plus vite.";
                }
            }
            if(orderType == 4){
                if(0 == m){
                    describe = language == 1 ? "您的包裹订单已超时,请抓紧!" : language == 2 ? "Your delivery order is overdue, please go faster." : "Votre commande de Delivery est en retard, veuillez aller plus vite.";
                }else{
                    describe = language == 1 ? "您的包裹订单已超时" + m + "分钟,请抓紧!" : language == 2 ? "Your delivery order is overdue for " + m + " minute(s), please go faster." : "Votre commande de livraison est en retard depuis " + m + " minute(s), veuillez aller plus vite.";
                }
            }
        }
        
        
        if(1 == orderType){
            //结束预约单出发循环提醒定时
            TOrderPrivateCar orderPrivateCar = orderPrivateCarService.selectById(orderId);
            List<Integer> list = Arrays.asList(4, 5, 6, 7, 8, 9, 10, 11, 12);
            if(1 == timeOutType && list.contains(orderPrivateCar.getState())){
                JobKey key = jobExecutionContext.getJobDetail().getKey();
                boolean b = quartzUtil.deleteQuartzTask(key);
                if(!b){
                    log.error("定时任务关闭失败:" + key.toString());
                }
                return;
            }
            if(2 == timeOutType && (System.currentTimeMillis() >= timeOut || list.contains(orderPrivateCar.getState()))){
                JobKey key = jobExecutionContext.getJobDetail().getKey();
                boolean b = quartzUtil.deleteQuartzTask(key);
                if(!b){
                    log.error("定时任务关闭失败:" + key.toString());
                }
                return;
            }
            
            //结束超时循环提醒定时
            if(3 == timeOutType && list.contains(orderPrivateCar.getState())){
                JobKey key = jobExecutionContext.getJobDetail().getKey();
                boolean b = quartzUtil.deleteQuartzTask(key);
                if(!b){
                    log.error("定时任务关闭失败:" + key.toString());
                }
                return;
            }
            
            
        }
        if(4 == orderType){
            TOrderLogistics orderLogistics = orderLogisticsService.selectById(orderId);
            List<Integer> list = Arrays.asList(4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
            if(1 == timeOutType && list.contains(orderLogistics.getState())){
                JobKey key = jobExecutionContext.getJobDetail().getKey();
                boolean b = quartzUtil.deleteQuartzTask(key);
                if(!b){
                    log.error("定时任务关闭失败:" + key.toString());
                }
                return;
            }
            //结束超时循环提醒定时
            if(3 == timeOutType && list.contains(orderLogistics.getState())){
                JobKey key = jobExecutionContext.getJobDetail().getKey();
                boolean b = quartzUtil.deleteQuartzTask(key);
                if(!b){
                    log.error("定时任务关闭失败:" + key.toString());
                }
                return;
            }
        }
        
        String fileName = "orderTimeOut" + driverId + "_" + timeOutType + ".mp3";
        String audioUrl = null;
        try {
            audioUrl = TextToSpeechUtil.create(language == 1 ? "cmn-CN" : language == 2 ? "en-US" : "fr-FR", describe, fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        //定时任务删除语音文件
        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);
        
        log.info("开始推送提醒-{}:orderId={};orderType={};timeOutType={};describe={};audioUrl={}", System.currentTimeMillis(), orderId, orderType, timeOutType, describe, audioUrl);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 200);
        jsonObject.put("msg", "SUCCESS");
        jsonObject.put("method", "ORDER_TIME_OUT");
        Map<String, Object> map = new HashMap<>();
        map.put("timeOutType", timeOutType);
        map.put("orderId", orderId);
        map.put("orderType", orderType);
        map.put("describe", describe);
        map.put("audioUrl", audioUrl);
        jsonObject.put("data", map);
        
        //调用推送
        HttpHeaders headers = new HttpHeaders();
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //将请求头部和参数合成一个请求
        Map<String, String> params = new HashMap<>();
        params.put("msg", jsonObject.toJSONString());
        params.put("id", String.valueOf(driverId));
        params.put("type", String.valueOf(2));
        String s = HttpRequestUtil.postRequest(PushURL.zull_user_url + "/netty/sendMsgToClient", params);
        JSONObject jsonObject1 = JSON.parseObject(s, JSONObject.class);
        if(jsonObject1.getIntValue("code") != 200){
            System.err.println(jsonObject1.getString("msg"));
        }
        
    }
    
    
    @Override
    public void execute(JobExecutionContext jobExecutionContext){
        run(jobExecutionContext);
    }
    
    
    
    
}