18045010223
2025-07-07 0d3a683a0c97154b1f2e6657398664537e4e3e82
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
package org.yzh.web.endpoint;
 
import com.ruoyi.jt.domain.*;
import com.ruoyi.jt.service.*;
import io.github.yezhihao.netmc.core.annotation.Async;
import io.github.yezhihao.netmc.core.annotation.AsyncBatch;
import io.github.yezhihao.netmc.core.annotation.Endpoint;
import io.github.yezhihao.netmc.core.annotation.Mapping;
import io.github.yezhihao.netmc.session.Session;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.yzh.commons.util.BytesUtils;
import org.yzh.protocol.basics.JTMessage;
import org.yzh.protocol.commons.JT808;
import org.yzh.protocol.t808.*;
import org.yzh.web.model.entity.DeviceDO;
import org.yzh.web.model.enums.SessionKey;
import org.yzh.web.service.FileService;
 
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
 
import static org.yzh.protocol.commons.JT808.*;
 
@Slf4j
@Endpoint
@Component
@RequiredArgsConstructor
public class JT808Endpoint {
 
    private final FileService fileService;
 
    @Autowired
    private IJtDeviceService jtDeviceService;
    @Autowired
    private IJtDeviceLocationService jtDeviceLocationService;
 
    @Mapping(types = 终端通用应答, desc = "终端通用应答")
    public Object T0001(T0001 message, Session session) {
//        String clientId = message.getClientId();
//        System.out.println("终端响应通用应答数据终端手机号:" + clientId);
//        log.info("终端响应通用应答数据终端手机号:" + clientId);
//        int serialNo = message.getSerialNo();
//        System.out.println("终端响应通用应答数据消息流水号:" + serialNo);
//        log.info("终端响应通用应答数据消息流水号:" + serialNo);
//        System.out.println("终端响应通用应答数据message.getExtData():" +message.getExtData());
//        System.out.println("终端响应通用应答数据message:" + message);
//        log.info("终端响应通用应答数据message:" + message);
        session.response(message);
        return null;
    }
 
    @Mapping(types = 终端心跳, desc = "终端心跳")
    public void T0002(JTMessage message, Session session) {
    }
 
    @Mapping(types = 终端注销, desc = "终端注销")
    public void T0003(JTMessage message, Session session) {
        session.invalidate();
    }
 
    @Mapping(types = 查询服务器时间, desc = "查询服务器时间")
    public T8004 T0004(JTMessage message, Session session) {
        T8004 result = new T8004().setDateTime(LocalDateTime.now(ZoneOffset.UTC));
        return result;
    }
 
    @Mapping(types = 终端补传分包请求, desc = "终端补传分包请求")
    public void T8003(T8003 message, Session session) {
    }
 
 
    @Mapping(types = 终端注册, desc = "终端注册")
    public T8100 T0100(T0100 message, Session session) {
        DeviceDO device = new DeviceDO();
        device.setProtocolVersion(message.getProtocolVersion());
        device.setMobileNo(message.getClientId());
        device.setDeviceId(message.getDeviceId());
        device.setPlateNo(message.getPlateNo());
        System.out.println("" + device);
        T8100 result = new T8100();
        result.setResponseSerialNo(message.getSerialNo());
        result.setToken(message.getDeviceId() + "   ," + message.getPlateNo());
        //判断系统中是否存在设备号和车辆绑定
        if (this.jtDeviceService.isExistDevice(device)) {
            session.setAttribute(SessionKey.Device, device);
            result.setResultCode(T8100.Success);
        } else {
            result.setResultCode(T8100.NotFoundVehicle);
        }
        return result;
    }
 
    @Mapping(types = 终端鉴权, desc = "终端鉴权")
    public T0001 T0102(T0102 message, Session session) {
        session.register(message);
        DeviceDO device = new DeviceDO();
        String[] token = message.getToken().split(",");
        device.setProtocolVersion(message.getProtocolVersion());
        device.setMobileNo(message.getClientId());
        device.setDeviceId(token[0]);
        if (token.length > 1)
            device.setPlateNo(token[1]);
 
 
        T0001 result = new T0001();
        result.setResponseSerialNo(message.getSerialNo());
        result.setResponseMessageId(message.getMessageId());
        //判断系统中车辆存在状态
        if (this.jtDeviceService.isExistDevice(device)) {
            session.setAttribute(SessionKey.Device, device);
            result.setResultCode(T0001.Success);
        } else {
 
            result.setResultCode(T0001.Failure);
        }
 
        return result;
    }
 
    @Mapping(types = 查询终端参数应答, desc = "查询终端参数应答")
    public void T0104(T0104 message, Session session) {
        session.response(message);
    }
 
    @Mapping(types = 查询终端属性应答, desc = "查询终端属性应答")
    public void T0107(T0107 message, Session session) {
        session.response(message);
    }
 
    @Mapping(types = 终端升级结果通知, desc = "终端升级结果通知")
    public void T0108(T0108 message, Session session) {
    }
 
    /**
     * 异步批量处理
     * poolSize:参考数据库CPU核心数量
     * maxElements:最大累积4000条记录处理一次
     * maxWait:最大等待时间1秒
     */
    @AsyncBatch(poolSize = 2, maxElements = 4000, maxWait = 1000)
    @Mapping(types = 位置信息汇报, desc = "位置信息汇报")
    public void T0200(List<T0200> list) {
        this.jtDeviceLocationService.saveT0200s(list,true);
    }
 
    @Mapping(types = 定位数据批量上传, desc = "定位数据批量上传")
    public void T0704(T0704 message) {
        List<T0200> list = message.getItems();
        this.jtDeviceLocationService.saveT0200s(list,false);
    }
 
    @Mapping(types = {位置信息查询应答, 车辆控制应答}, desc = "位置信息查询应答/车辆控制应答")
    public void T0201_0500(T0201_0500 message, Session session) {
        session.response(message);
    }
 
    @Mapping(types = 事件报告, desc = "事件报告")
    public void T0301(T0301 message, Session session) {
    }
 
    @Mapping(types = 提问应答, desc = "提问应答")
    public void T0302(T0302 message, Session session) {
    }
 
    @Mapping(types = 信息点播_取消, desc = "信息点播/取消")
    public void T0303(T0303 message, Session session) {
    }
 
    @Mapping(types = 查询区域或线路数据应答, desc = "查询区域或线路数据应答")
    public void T0608(T0608 message, Session session) {
        session.response(message);
    }
 
    @Mapping(types = 行驶记录数据上传, desc = "行驶记录仪数据上传")
    public void T0700(T0700 message, Session session) {
        session.response(message);
    }
 
    @Mapping(types = 电子运单上报, desc = "电子运单上报")
    public void T0701(JTMessage message, Session session) {
    }
 
    @Mapping(types = 驾驶员身份信息采集上报, desc = "驾驶员身份信息采集上报")
    public void T0702(T0702 message, Session session) {
        session.response(message);
    }
 
    @Mapping(types = CAN总线数据上传, desc = "CAN总线数据上传")
    public void T0705(T0705 message, Session session) {
    }
 
    @Mapping(types = 多媒体事件信息上传, desc = "多媒体事件信息上传")
    public void T0800(T0800 message, Session session) {
    }
 
    @Async
    @Mapping(types = 多媒体数据上传, desc = "多媒体数据上传")
    public JTMessage T0801(T0801 message, Session session) {
        if (message.getPacket() == null) {
            T0001 result = new T0001();
            result.copyBy(message);
            result.setMessageId(JT808.平台通用应答);
            result.setSerialNo(session.nextSerialNo());
 
            result.setResponseSerialNo(message.getSerialNo());
            result.setResponseMessageId(message.getMessageId());
            result.setResultCode(T0001.Success);
            return result;
        }
        fileService.saveMediaFile(message);
        T8800 result = new T8800();
        result.setMediaId(message.getId());
        return result;
    }
 
    @Mapping(types = 存储多媒体数据检索应答, desc = "存储多媒体数据检索应答")
    public void T0802(T0802 message, Session session) {
        session.response(message);
    }
 
    @Mapping(types = 摄像头立即拍摄命令应答, desc = "摄像头立即拍摄命令应答")
    public void T0805(T0805 message, Session session) {
        session.response(message);
    }
 
    @Mapping(types = 数据上行透传, desc = "数据上行透传")
    public void T0900(T0900 message, Session session) {
        // session.response(message);
        // 获取终端手机号和消息流水号
        String clientId = message.getClientId();
        System.out.println("终端响应T0900数据终端手机号:" + clientId);
        log.info("终端响应T0900数据终端手机号:" + clientId);
        int serialNo = message.getSerialNo();
        System.out.println("终端响应T0900数据消息流水号:" + serialNo);
        log.info("终端响应T0900数据消息流水号:" + serialNo);
//        JtDevice jtDevice=new JtDevice();
//        jtDevice.setClientId(message.getClientId());
//        List<JtDevice> list = jtDeviceService.selectJtDeviceList(jtDevice);
//        //JtDevice jd=list.get(0);
//        ArdTankLock ardTankLock=null;
//
//        if(!list.isEmpty()){
//            //ardTankLock.setCarId(list.get(0).getId());
//            ardTankLock = ardTankLockService.selectArdTankLockByCarId(list.get(0).getId());
//
//        }
        int key;
        byte[] value=null;
        if(message.getMessage()!=null) {
            key = message.getMessage().getKey();
            value = (byte[]) message.getMessage().getValue();
//            Base64.getUrlDecoder().decode(message.getMessage().getValue().toString());
            String va=BytesUtils.bytes2hex(value);
            System.out.println("终端响应T0900数据key:" + key);
            log.info("终端响应T0900数据key:" + key);
 
            System.out.println("终端响应T0900数据value:" + va);
            log.info("终端响应T0900数据value:" + va);
 
            //测试数据,读所有信息
            //value=BytesUtils.hex2bytes("00010B02010102007300E61906180B1414010001020304051906180A0000000102030405061906190A000000020304050607FFFFFFFFFFFFFF030405060708FFFFFFFFFFFFFF040506070809FFFFFFFFFFFFFF050607080900FFFFFFFFFFFFFF060708090001FFFFFFFFFFFFFF070809000102FFFFFFFFFFFFFF080900010203FFFFFFFFFFFFFF090001020304FFFFFFFFFFFFFF2F");
            String ins = String.valueOf(value[2]);
            if(ins.equals("11"))
            {//读所有信息
                System.out.println("终端响应T0900数据为读所有信息:" + ins);
                log.info("终端响应T0900数据为读所有信息:" + ins);
//                ArdTankLockState lock = AnalysisUtils.analysis(value,ardTankLock.getId(),ardTankLock.getCarId());
//                lockService.insertArdTankLockState(lock);
                //设备密码
 
            }
            if(ins.equals("9"))
            {//读设备号
                System.out.println("终端响应T0900数据为读设备号:" + ins);
                log.info("终端响应T0900数据为读设备号:" + ins);
            }
            if(ins.equals("2"))
            {//设置锁状态(开锁关锁)
                System.out.println("终端响应T0900数据为设置锁状态:" + ins);
                log.info("终端响应T0900数据为设置锁状态:" + ins);
            }
            if(ins.equals("1"))
            {//读锁当前状态
                System.out.println("终端响应T0900数据为读锁当前状态:" + ins);
                log.info("终端响应T0900数据为读锁当前状态:" + ins);
            }
 
 
        }
        //return T8900ReadLockIdResponse.parseFromBytes(value);
 
    }
 
    @Mapping(types = 数据压缩上报, desc = "数据压缩上报")
    public void T0901(T0901 message, Session session) {
    }
 
    @Mapping(types = 终端RSA公钥, desc = "终端RSA公钥")
    public void T0A00(T0A00_8A00 message, Session session) {
        session.response(message);
    }
 
    @Mapping(types = 数据下行透传, desc = "多业务透传处理")
    public void T8900(T8900 message, Session session) {
        //数据下行透传
        //消息透传应答
        session.response(message);
 
        try {
            // 解析响应数据
 
            //byte[] responseData = message.getData();
//            byte responseStatus = T8900.parseValveResponse(responseData);
 
            // 获取终端手机号和消息流水号
            String clientId = message.getClientId();
            System.out.println("终端响应8900数据终端手机号:" + clientId);
            log.info("终端响应8900数据终端手机号:" + clientId);
            int serialNo = message.getSerialNo();
            System.out.println("终端响应8900数据消息流水号:" + serialNo);
            log.info("终端响应8900数据消息流水号:" + serialNo);
            System.out.println("终端响应8900数据message:" + message);
            log.info("终端响应8900数据message:" + message);
 
        } catch (Exception e) {
//            logger.error("处理蝶阀锁响应消息出错", e);
        }
    }
 
//    @Mapping(types = 消息透传应答, desc = "多业务透传处理")
//    public void T8901(T8900 message, Session session) {
//        //数据下行透传
//        //消息透传应答
//        session.response(message);
//        // 获取终端手机号和消息流水号
//        String clientId = message.getClientId();
//        System.out.println("终端响应8901数据终端手机号:" + clientId);
//        log.info("终端响应8901数据终端手机号:" + clientId);
//        int serialNo = message.getSerialNo();
//        System.out.println("终端响应8901数据消息流水号:" + serialNo);
//        log.info("终端响应8901数据消息流水号:" + serialNo);
//        System.out.println("终端响应8900数据message:" + message);
//        log.info("终端响应8901数据message:" + message);
//    }
 
//    // 处理透传响应(消息ID与请求一致,均为0x8900)  zwy20250610
//    @Mapping(types = 0x8900)
//    public T8900Response handleValveLockResponse(T8900Response response, Session session) {
//        // 可在此添加业务逻辑(如记录状态到数据库)
//        return response;
//    }
}